const colors = require('colors');

const exec = require('@x3-cli-dev/exec');
const log = require('@x3-cli-dev/log');

function registerGlobal(program) {
  const pkg = require('../package.json');
  program
    .name(Object.keys(pkg.bin)[0])
    .usage('<command> [options]')
    .version(pkg.version, '-v, --version', '显示版本号')
    .addHelpCommand('help [command]', '显示命令帮助信息')
    .helpOption('-h, --help', '显示帮助信息')
    .addHelpText('afterAll', `\n${colors.green('更多详情请查看在线文档')} ${colors.blue(pkg.homepage)}`)
    .option('-d, --debug', '是否启用调试模式')
    .option('-tp, --target-path <targetPath>', '是否指定本地调试路径');

  // 开启 debug 模式
  program.on('option:debug', () => {
    const opts = program.opts();
    if (opts.debug) {
      process.env.LOG_LEVEL = 'verbose';
    } else {
      process.env.LOG_LEVEL = 'info';
    }
    log.level = process.env.LOG_LEVEL;
    log.verbose(`debug mode`);
  });

  // 对未知命令监听
  program.on('command:*', args => {
    const availableCommands = program.commands.map(cmd => cmd.name());
    console.log(colors.red('未知的命令：' + args[0]));
    if (availableCommands.length > 0) {
      console.log(colors.red('可用命令：' + availableCommands.join(', ')));
    }
  });

  // 指定执行路径
  program.on('option:target-path', targetPath => {
    process.env.X3_CLI_TARGET_PATH = targetPath;
  });
}

function registerInit(program) {
  program
    .command('init <projectName>')
    .description('初始化项目')
    .option('-f, --force', '强制覆盖目标目录(如果存在)')
    .option('-si, --skip-install', '跳过依赖安装')
    .action(exec);
}

function registerPublish(program) {
  program
    .command('publish')
    .description('发布项目')
    .option('-sbu, --skip-build', '跳过项目打包')
    .option('-sba, --skip-backup', '跳过服务器文件备份')
    .option('-u, --use <server>', '指定服务器配置')
    .option('-app, --application <application name>', '指定发布的应用名')
    .action(exec);
}

function registerSvn(program) {
  program
    .command('svn')
    .description('SVN 发布')
    .option('-u, --use <environment>', '指定svn根路径')
    .option('-f, --force', '不询问，直接发布')
    .option('-app, --application <application name>', '指定发布的应用名')
    .requiredOption('-m, --message <message>', '提交信息')
    .action(exec);
}

function registerConfig(program) {
  program
    .command('config')
    .description('配置增删改查')
    .option('--set <keyValue...>', '设置 config, 可同时设置多个, 如 x3 -s key1 value1 key2 value2')
    .option('--get <keys...>', '查询 config, 可同时查询多个, 如 x3 -g key1 key2 key3')
    .option('-del, --delete <keys...>', '删除 config, 可同时删除多个, 如 x3 -d key1 key2 key3')
    .option('-ls, --list', '查看所有 config')
    .option('--edit', '编辑 config, 使用 vim 编辑器')
    .option('-lis, --list-server', '查看服务器配置列表')
    .option('-as, --add-server <server>', '添加服务器配置')
    .option('-rs, --remove-server <server>', '删除服务器配置')
    .option('-us, --use-server <server>', '使用指定的服务器配置')
    .action(exec);
}

function registerClean(program) {
  program
    .command('clean')
    .description('清除缓存, 默认情况下只清除 command 缓存')
    .option('-f, --force', '不询问，强制删除')
    .option('-t, --template', '清楚包含模板缓存')
    .action(exec);
}

function registerInstall(program) {
  program
    .command('install')
    .description('安装本地依赖到本地仓库')
    .argument('<source>', '要安装的本地依赖 PackageName')
    .argument('<destination>', '要安装的目的仓库 PackageName')
    .option('-sbu, --skip-build', '跳过项目打包')
    .option('-spa, --skip-pack', '跳过 npm pack')
    .action(exec);
}

function registerProxy(program) {
  program
    .command('proxy')
    .description('启动本地代理')
    .option('-ls, --list [proxy-name]', '查看环境代理')
    .option('-u, --use <proxy-name>', '使用环境代理')
    .option('-e, --edit', '编辑 proxy, 使用 vim 编辑器')
    .option('-p, --port <number>', '代理启动端口号，默认 3000')
    .action(exec);
}


module.exports = {
  registerGlobal,
  registerInit,
  registerPublish,
  registerSvn,
  registerConfig,
  registerClean,
  registerInstall,
  registerProxy,
}
